#ifndef _LINUX_PI_DEV_H
#define _LINUX_PI_DEV_H

#include <linux/types.h>
#include "drv_pcie.h"
#include "drv_pcie_irq.h"
#include "drv_cdev.h"

#define PI_MAX_CHANNEL              4       /* PI 最大通道数 */
#define PI_FREQ_ZOOM                1000    /* PI 频率放大倍数 */

/* IOCTL 命令定义 */
#define IOCTL_PI_MAGIC                  'P'                                 /* 标识设备驱动 */
#define IOCTL_PI_SET_EDGE               _IOW(IOCTL_PI_MAGIC, 1, u8)         /* 配置 PI 边沿 */
#define IOCTL_PI_SET_FILTER             _IOW(IOCTL_PI_MAGIC, 2, u16)        /* 配置 PI 滤波时间 */

#define IOCTL_PI_GET_EDGE               _IOR(IOCTL_PI_MAGIC, 51, u8)        /* 核查 PI 边沿 */
#define IOCTL_PI_CHK_FILTER             _IOR(IOCTL_PI_MAGIC, 52, u16)       /* 核查 PI 滤波时间 */

#define IOCTL_PI_GET_DRV_VERSION        _IOR(IOCTL_PI_MAGIC, 101, u32)      /* 获取驱动版本号 */
#define IOCTL_PI_GET_FPGA_VERSION       _IOR(IOCTL_PI_MAGIC, 102, u32)      /* 获取 FPGA 版本号 */

// enum pi_cmd {
//     PI_CMD_START        = 0x4444,   /* 开始 PI 频率测量指令 */
// };

enum pi_mode {
    PI_MOD_FREQ         = 1,        /* 测量频率 */
};

enum pi_edge {
    /* 硬件为反逻辑，须软件反转边沿寄存器电平 */
    PI_EDGE_RISE        = 1,        /* 上升沿 */
    PI_EDGE_FALL        = 0,        /* 下降沿 */
    PI_EDGE_RISE_FALL   = 2,        /* 上升和下降沿 */
};

enum pi_type {
    PI_TYPE_DEF         = 0,        /* PI 默认类型 */
    PI_TYPE_AC          = 1,        /* PI AC 卡类型 */
};

/* PI 设备 */
struct pi_dev_t {
    void *parent;                   /* 父设备指针 */
    struct device *dev;             /* 设备描述符 */
    struct mutex lock;              /* 互斥锁 */
    char name[32];                  /* 设备名称 */
    u8 index;                       /* 索引号 */

    u8 edge;                        /* 边沿 */
    u8 edge_get;                    /* 边沿获取值 */
    u16 delay;                      /* 延时时间, us */
    u16 delay_get;                  /* 延时时间获取值 */
    u32 cycle;                      /* 周期值, ns */
};

/* PI 控制器 */
struct pi_ctrl_t {
    struct device *dev;                                                 /* 设备描述符 */
    struct mutex lock;                                                  /* 互斥锁 */
    char name[32];                                                      /* 设备名称 */
    u8 num;                                                             /* 设备数量 */

    struct pcie_dev_t *pcie_dev;                                        /* PCIe 设备指针 */
    u32 (*read_reg)(struct pcie_dev_t *pcie_dev, u32 reg);              /* 读寄存器 */
    void (*write_reg)(struct pcie_dev_t *pcie_dev, u32 reg, u32 val);   /* 写寄存器 */
    struct cdev_ctrl_t cdev_ctrl;                                       /* 字符设备控制器 */
    struct pcie_irq_ctrl_t irq_ctrl;                                    /* 中断控制器 */
    struct pi_dev_t *pi;                                                /* PI */
    u8 type;                                                            /* PI 模式 */
    u8 id[PI_MAX_CHANNEL];                                              /* PI 通道顺序 */

    u32 drv_ver;                                                        /* 驱动版本号 */
    u32 fpga_ver;                                                       /* FPGA 版本号 */
};

/* 初始化 PI 控制器 */
int init_pi_ctrl(struct pcie_dev_t *pcie_dev, struct cdev_dev_t *cdev_dev, 
                 struct pi_ctrl_t *pctrl, struct pi_dev_t *pi, 
                 const char *ctrl_name, u8 dev_num, u8 type);
/* 注销 PI 控制器 */
void exit_pi_ctrl(struct pi_ctrl_t *ctrl, u8 dev_num);

#endif /* _LINUX_PI_DEV_H */
